#!/usr/bin/env python
#encoding: latin1

import sys

class Nodo(object):
	""" Clase nodo. """
	def __init__(self, indice, numero, nombre):
		""" Crea nodo. Recibe todo en string. """
		self._indice = int(indice)
		self._numero = numero
		self._nombre = nombre
		self._adyacentes = [] 
		self._grado_entrada = 0
		self.influencia = float(0)
	
	def numero(self):
		""" Devuelve numero. """
		return self._numero

	def nombre(self):
		""" Devuelve nombre. """
		return self._nombre

	def grado_entrada(self):
		""" Devuelve el grado de entrada. """
		return self._grado_entrada
		
	def agrega_adyacente(self, adyacente):
		""" Agrega un adyacente"""
		self._adyacentes.append(adyacente)
		self._grado_entrada += 1
			
	def adyacentes(self):
		""" Devuelve lista con todos los adyacentes. """
		return self._adyacentes

	def __str__(self):
		return self.nombre()

	def __repr__(self):
		return self.nombre()
	
class Grafo(object):
	""" Clase grafo. """
	def __init__(self):
		""" Crea grafo. """
		self.nodos = []
		self.diccionario_nodos = {} #clave: numero, valor: nodo
						  
	def agrega_nodo(self, nodo):
		""" Agrega un nodo al grafo. nodo es de clase Nodo. """
		self.nodos.append(nodo)
		self.diccionario_nodos[nodo.numero()] = nodo
		
	def agrega_arista(self, numero_nodo_inicial, numero_nodo_final):
		""" Agrega una arista al grafo. numero_nodo es de tipo string """
		nodo_inicial = self.diccionario_nodos[numero_nodo_inicial]
		nodo_final = self.diccionario_nodos[numero_nodo_final]
		
		nodo_inicial.agrega_adyacente(nodo_final)
		nodo_final.agrega_adyacente(nodo_inicial)

	def get_nodo_vacio(self):
		nodo = Nodo(0,0," ")
		return nodo
		
	def esta_vacio(self):
		"""Devuelve True si el grafo está vacío, caso contrario devuelve False"""
		if len(self.nodos) == 0:
			return True
		return False

		
class Lector(object):
	def __init__(self, arch, grafo):
		self.grafo = grafo
		self.archivo = arch
			
		self.leer()

	def crear_nodo(self, linea, indice):
		try:
			numero, nombre, sexo, localizacion, rank = linea.split(",")
			nodo = Nodo(indice, numero, nombre)
			self.grafo.agrega_nodo(nodo)
		except TypeError:
			print "Nodo con formato incorrecto."
			return
	
	def crear_arista(self, linea):
		try:
			numero_nodo_inicial, numero_nodo_final = linea.split(",")
			self.grafo.agrega_arista(numero_nodo_inicial, numero_nodo_final)
		except TypeError:
			print "Arista con formato incorrecto."
			return

	def leer(self):
		indice_nodo = 0
		try:
			with open(self.archivo, 'r') as f:
				for linea in f:
					if "nodedef" in linea:
						cargar_nodo = True
						cargar_arista = False
					elif "edgedef" in linea:
						cargar_arista = True
						cargar_nodo = False
					elif cargar_nodo == True:
						self.crear_nodo(linea, indice_nodo)
						indice_nodo += 1
					elif cargar_arista == True:
						self.crear_arista(linea.replace("\n", ""))
		except:
			print "Error al abrir el archivo."

def comparar_grado_entrada(nodo1, nodo2):
	""" Funcion de comparacion de nodos segun el grado de entrada."""
	if nodo1.grado_entrada() > nodo2.grado_entrada():
		return -1
	elif nodo1.grado_entrada() < nodo2.grado_entrada():
		return 1
	else:
		return 0

def comparar_influencia(nodo1, nodo2):
	""" Funcion de comparacion de nodos segun influencia."""
	if nodo1.influencia > nodo2.influencia:
		return -1
	elif nodo1.influencia < nodo2.influencia:
		return 1
	else:
		return 0
